﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Framework.FSM;
using BridgeShips.AI;
using Framework.Entity;
namespace BridgeShips.FSM
{


    public class VStartJumpGpsFirstPositionState : IFsmState
    {

        private uint m_virtrualID = 0; //ship id
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;

            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;
            ShipProperty.ShipsType type = (ShipsDictionary.Instance.GetShipPropertyType(fsdb.vShipID));
            if (type == ShipProperty.ShipsType.None)
            {
                return;
            }
        }
    }
    /*
     *  辅助并线 对号 虚拟席位
     */

    public class VAddressCorrectState : IFsmState
    {

        private uint m_virtrualID = 0; //ship id
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;
            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;
            ShipProperty.ShipsType type = (ShipsDictionary.Instance.GetShipPropertyType(fsdb.vShipID));
            if (type == ShipProperty.ShipsType.None)
            {
                return;
            }
            else if ((int)(type) == fsdb.type)
            {
                GameEntry.Instance.FsmManager.GetFsm(fsdb.virtualObj.name).ChangeState<VProbeState>(fsdb);
            }
            else if (type < ShipProperty.ShipsType.None)
            {
                GameEntry.Instance.VirtualRManager.SwapModel(m_virtrualID, (int)(type));
            }
        }
    }

    /*
     *  辅助并线 对号 探测状态
     */
    public class VProbeState : IFsmState
    {
        private float m_KeepTime = 0.0f;
        private uint m_virtrualID = 0; //ship id
        private int m_needChangeRotation = -1;
        private bool m_GrowLenAtBottom = true;
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
            m_KeepTime = Time.time;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;
            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform(fsdb.vShipID);
            if (trans == null)
                return;

            int needVShipRoation = CaculateLeftOrRight(trans.position);
            if (m_needChangeRotation != needVShipRoation)
            {
                float needDeg = (needVShipRoation * 0.5f + 0.5f) * 180.0f;
                fsdb.virtualObj.transform.localRotation = Quaternion.Euler(Vector3.up * needDeg);
                m_needChangeRotation = needVShipRoation;
            }
            float distance = Vector3.Distance(fsdb.virtualObj.transform.position, trans.position);
            if (Time.time - m_KeepTime > 10.0f &&  (distance  < fsdb.length* 0.5f))
            {
                GameEntry.Instance.FsmManager.GetFsm(fsdb.virtualObj.name).ChangeState<VPosCorrectState>(fsdb);
                m_KeepTime = Time.time;
            }
            else
            {
                Vector3 bottomRightPos = TransferOfAxes.Instance.m_BottomRightPoint.position;
                Vector3 topRight = TransferOfAxes.Instance.m_TopRightPoint.position;
                if (fsdb.index <= (GameEntry.Instance.VirtualRManager.GetVirtualShipCount() - 1) / 2)
                {

                    bool newGrow = ((Vector3.Distance(bottomRightPos, trans.position) + Vector3.Distance(topRight, trans.position)) < TransferOfAxes.Instance.GetRiverWidth() + fsdb.length) ? false : true;
                    newGrow = newGrow && (Vector3.Distance(fsdb.virtualObj.transform.position, trans.position) < fsdb.length);
                    if (newGrow != m_GrowLenAtBottom)
                    {
                        m_GrowLenAtBottom = newGrow;
                        GameEntry.Instance.VirtualRManager.ChangeGrowDirection(m_GrowLenAtBottom);
                    }
                }
            }
        }

        public int CaculateLeftOrRight(Vector3 shipPosition)
        {
            Vector3 verticalDir = TerrainsMove.Instance.GetBridgePoint2().position - TerrainsMove.Instance.GetBridgePoint1().position;
            verticalDir.Normalize();
            Vector3 direction = (shipPosition - TerrainsMove.Instance.GetBridgePoint1().position).normalized;
            int flag = 1;  //左0 右1
            if (Vector3.Cross(direction, verticalDir).y > 0)
            {
                flag = -1;
            }
            else
            {
                flag = 1;
            }
            return flag;
        }
    }


    /*
     *  辅助并线 席位矫正
     */
    public class VPosCorrectState : IFsmState
    {


        private uint m_virtrualID = 0; //ship id
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;
            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform(fsdb.vShipID);
            if (trans == null)
                return;
            IEntity entity = GameEntry.Instance.EntityManager.Get(fsdb.vShipID);
            if (entity == null)
                return;
            ET.AIMovementState mstate = entity.GetAI().ShipMoveState();

            var virObj = fsdb.virtualObj;
            float distance = Vector3.Distance(trans.position, virObj.transform.position);
            if (distance < 0.05f && mstate < ET.AIMovementState.GpsDriving)
            {
                GameEntry.Instance.FsmManager.GetFsm(virObj.name).ChangeState<VIdleState>(fsdb);
            }
            else
            {
                var meshRender = fsdb.virtualObj.GetComponentInChildren<MeshRenderer>();
                if (meshRender != null)
                {
                    meshRender.material.SetFloat("_WireThickness", Mathf.Clamp(150.0f * distance + 580.0f, 500.0f, 760.0f));

                }

                Vector3 vecDestination = virObj.transform.position; 
                entity.GetAI().Settings.Movement.MoveTo(vecDestination, virObj.transform.forward);

                if (entity.GetAI().Settings.IsDone())
                {
                    GameEntry.Instance.FsmManager.GetFsm(fsdb.virtualObj.name).ChangeState<VLinkingState>(fsdb);
                    return;
                }
            }
        }
    }


    /*
     *  辅助并线 等待状态
     */
    public class VIdleState : IFsmState
    {


        private uint m_virtrualID = 0; //ship id
                                       // Use this for initialization
                                       /// <summary>
                                       /// 状态初始化接口
                                       /// </summary>
                                       /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// VIdleState 等待链接
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;
            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform(fsdb.vShipID);
            if (trans == null)
                return;

            Vector3 newTargetPos = ShipsDictionary.Instance.GetPoisition(fsdb.vShipID);
            float distance = Vector3.Distance(fsdb.virtualObj.transform.position, newTargetPos);
            if (distance > fsdb.length)
            {
                GameEntry.Instance.FsmManager.GetFsm(fsdb.virtualObj.name).ChangeState<VLeaveState>(fsdb);
            }
            else
            {
                GameEntry.Instance.EntityManager.LerpForwardLocalRotation(trans, fsdb.virtualObj.transform.localRotation,10.0f,1.0f);
                float fRemainDistance = GameEntry.Instance.EntityManager.LerpPosition(trans, fsdb.virtualObj.transform.position,10.0f,0.1f);
            }
        }
    }

    
    /*
     *  辅助并线 等待状态
     */
    public class VLinkingState : IFsmState
    {

        private uint m_virtrualID = 0; //ship id
        private float m_realKeepTime = 0.0f;//链接保持时间
        private float m_MaxKeepTime = 30.0f;//最大准备链接保持时间
                                            // Use this for initialization
                                            /// <summary>
                                            /// 状态初始化接口
                                            /// </summary>
                                            /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {
            m_realKeepTime = 0.0f;
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;
            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;

            m_realKeepTime += frameTime;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform(fsdb.vShipID);
            if (trans == null)
                return;
            GameEntry.Instance.FsmManager.GetFsm(fsdb.virtualObj.name).ChangeState<VIdleState>(fsdb);
            IEntity entity = GameEntry.Instance.EntityManager.Get(fsdb.vShipID);
            if (entity != null)
            {
                bool bePreShip = false;
                if (m_realKeepTime >= m_MaxKeepTime)
                {
                    VehicleEntityManager.EntityLinkInfo eli = GameEntry.Instance.VehicleEntityManager.GetEntityLinkedInfo(fsdb.vShipID);
                    if (eli.IsValid() == false)
                        return;
                    eli.bLinked = true;
                    eli.FillID(bePreShip, fsdb.vlinkingTargetID);

                    GameEntry.Instance.VehicleEntityManager.RecordEntityLinkedInfo(fsdb.vShipID, eli);
                    entity.GetAI().Settings.Movement.MakeLinked(true);
                    StateData.OverrideValue(HelpStrings.AI.IS_SHIP_LINKED, entity.GetAI().Settings.Detection.HasTarget(), entity.GetAI().WorldState);
                }
                else
                {
                    bePreShip = fsdb.vShipID > fsdb.vlinkingTargetID ? false : true;
                }
            }
        }
    }

    /*
     *  辅助并线 等待状态
     */
    public class VLeaveState : IFsmState
    {

        private uint m_virtrualID = 0; //ship id
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter(IFSM fsm, FsmStateDataBase data)
        {
            m_virtrualID = data.index;
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit(IFSM fsm)
        {

        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy(IFSM fsm)
        {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update(float frameTime, float realTime)
        {

            if (!GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection())
                return;
            if (m_virtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_virtrualID);
            if (fsdb == null)
                return;

            VehicleEntityManager.EntityLinkInfo eli = GameEntry.Instance.VehicleEntityManager.GetEntityLinkedInfo(fsdb.vShipID);
            if (eli.IsValid() == false)
                return;
            eli.Clear();
            GameEntry.Instance.VehicleEntityManager.RecordEntityLinkedInfo(fsdb.vShipID, eli);
        }
    }
}
